Snowball_233

Snowball_233

A student who is learning coding.

rm によって削除されたが、プロセスによって使用されているファイルを回復する

先月、非常不運な出来事がありました。私はMinecraftサーバーのメニューシステムを作成するためにワクワクしながら準備していたところ、なぜかTermiusが元々書きたかった 'cd ./server' を 'rm -rf ./server' と自動補完してしまいましたが、最終的には95%以上のデータを無事に回復することができました。

適用範囲#

  • ファイルはまだキャッシュで実行されています。したがって、回復中にプロセスを終了したりシャットダウンしたりすることはできません。

手順#

  1. ファイルを誤って削除しましたが、そのファイルはプロセスによって使用されています。

    $ rm test.sh
    
  2. lsof コマンドを使用して、削除されたがまだプロセスによって使用されているファイルをリストします。

    $ lsof | grep -i delete | grep speed
    sh  6567  root  4r  REG  253,0  865  /home/test.sh(deleted)
    
    • ここで、最初の項目 sh はプロセス名であり、2 番目の項目 6567 はプロセス ID です。
  3. プロセスディレクトリに移動します。

    $ cd /proc/6567/fd
    $ ls -la
    lr-x------. 1 root root 64 July 13 02:10 4 -> /home/test.sh (deleted)
    
    • ここで、9 番目の項目 4 はファイルディスクリプタです。
  4. 回復します。

    $ cat 4 > /home/test.sh
    

フォルダの回復#

  • フォルダが同時に削除された場合、このような手動の回復は非常に手間がかかります。特に、小さなファイルが多い場合は非常に困難です。そのため、バッチ処理で回復を行うことをお勧めします。

  • その前に、ステップ 1 で回復するすべてのファイルをログファイルにエクスポートする必要があります。ここでは詳細に触れません。

    use std::fs;
    use std::io::Read;
    
    fn main() {
        let mut log_file = fs::File::open("/home/deleted_files.log").unwrap(); // 回復するファイルリストのパスを入力してください
        let mut logs = String::new();
        log_file.read_to_string(&mut logs).unwrap();
        let mut command = String::new();
        let mut paths = Vec::new();
    
        let logs = logs.split("\n");
    
        for log in logs {
            let log = log.split_whitespace().collect::<Vec<&str>>();
    
            if log.len() < 12 {
                continue;
            }
    
            let number = log[8]; // 8はファイルディスクリプタの列数です。ファイルの実際の状況に合わせて変更してください
            let path = log[10]; // 10は元のファイルパスの列数です。ファイルの実際の状況に合わせて変更してください
    
            if !path.starts_with("/home") { // 回復先のターゲットフォルダを入力してください
                continue;
            }
    
            println!("{}: {}", number, path);
            command.push_str(format!("cat {} > ~/recovery{}\n", number, path).as_str());
    
            let path = path.split("/").collect::<Vec<&str>>();
            let path = path[..path.len() - 1].join("/");
            let path = format!("~/recovery{}", path);
    
            if !paths.contains(&path) {
                paths.push(path);
            }
        }
    
        let mut complete_cmd = String::new();
    
        for path in paths {
            complete_cmd.push_str(format!("mkdir -p {}\n", path).as_str());
        }
    
        println!("{}", complete_cmd);
        complete_cmd.push_str(&command);
    
        fs::write("recovery.sh", complete_cmd).unwrap();
    }
    
  • 最後に、生成された recovery.sh を実行してすべてのファイルを回復します。


注意: Minecraft サーバーではプレイヤーデータを直接回復することはできず、この方法では削除されたすべてのファイルを 100%回復することは保証されません。ファイルのバックアップを定期的に行い、後悔を誤った削除の結果にしないようにしてください。

この記事は Mix Space からの同期更新で、xLog に掲載されています。
元のリンクは https://blog.rescueme.life/posts/devops/restore-files-deleted-by-rm-but-occupied-by-processes です。


読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。